package hn.cch.grammar.security;

import java.io.File;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.security.Key;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Enumeration;

/**
 * 数字证书
 */
public class KeyUtil {


    private static String KeyStoreType = "PKCS12";

    private static String CertificateFactoryType = "X.509";


    public static String sign(String filePath, String passWord, String jsonText) {

        try {

            KeyStore keyStore = KeyStore.getInstance(KeyStoreType);
            InputStream inputStream = Files.newInputStream(new File(filePath).toPath());
            keyStore.load(inputStream, passWord.toCharArray());
            Enumeration<String> aliases = keyStore.aliases();

            while (aliases.hasMoreElements()) {
                String alias = aliases.nextElement();
                Key key = keyStore.getKey(alias, passWord.toCharArray());

                if (key instanceof PublicKey) {

                    System.out.println("PublicKey");

                    // PublicKey publicKey = (PublicKey) key;
                    // X509Certificate x509Certificate = (X509Certificate) keyStore.getCertificate(alias);
                    // String sigalg = x509Certificate.getSigAlgName();
                    // Signature signature = Signature.getInstance(sigalg);
                    // signature.initVerify(publicKey);
                    // signature.update(BytesUtil.fromHex(jsonText));
                    // System.out.println("verify : " + signature.verify(StringUtil.toBytes(jsonText)));
                }

                if (key instanceof PrivateKey) {

                    System.out.println("PrivateKey");

                    PrivateKey privateKey = (PrivateKey) key;
                    X509Certificate x509Certificate = (X509Certificate) keyStore.getCertificate(alias);
                    String sigalg = x509Certificate.getSigAlgName();
                    Signature signature = Signature.getInstance(sigalg);
                    signature.initSign(privateKey);
                    signature.update(jsonText.getBytes(StandardCharsets.UTF_8));
                    return HexUtil.toHex(signature.sign());

                }
            }

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return new String();
    }


    public static boolean verify(String filePath, String signData, String jsonText) {

        try {

            // CertificateFactory certificateFactory = CertificateFactory.getInstance(CertificateFactoryType);
            // InputStream inputStream = StreamUtil.toInput(new File(filePath));
            // X509Certificate x509Certificate = (X509Certificate)certificateFactory.generateCertificate(inputStream);
            // String sigAlg = x509Certificate.getSigAlgName();
            // Signature signature = Signature.getInstance(sigAlg);
            // signature.initVerify(x509Certificate);
            // signature.update(StringUtil.toBytes(jsonText));
            // return signature.verify(BytesUtil.fromHex(signData));


            CertificateFactory certificateFactory = CertificateFactory.getInstance(CertificateFactoryType);
            InputStream inputStream = Files.newInputStream(new File(filePath).toPath());
            X509Certificate x509Certificate = (X509Certificate) certificateFactory.generateCertificate(inputStream);

            PublicKey publicKey = x509Certificate.getPublicKey();

            String sigalg = x509Certificate.getSigAlgName();
            Signature signature = Signature.getInstance(sigalg);

            signature.initVerify(publicKey);
            signature.update(jsonText.getBytes(StandardCharsets.UTF_8));
            return signature.verify(HexUtil.fromHex(signData));


        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return false;
    }

    public static boolean verify1(String filePath, String passWord, String jsonText) {

        try {

            KeyStore keyStore = KeyStore.getInstance(KeyStoreType);
            InputStream inputStream = Files.newInputStream(new File(filePath).toPath());

            // CertificateFactory certificateFactory = CertificateFactory.getInstance(CertificateFactoryType);
            // X509Certificate x509Certificate = (X509Certificate) certificateFactory.generateCertificate(inputStream);

            keyStore.load(inputStream, passWord.toCharArray());
            Enumeration<String> aliases = keyStore.aliases();

            while (aliases.hasMoreElements()) {
                String alias = aliases.nextElement();
                Key key = keyStore.getKey(alias, passWord.toCharArray());

                if (key instanceof PublicKey) {

                    System.out.println("PublicKey");

                    PublicKey publicKey = (PublicKey) key;
                    X509Certificate x509Certificate = (X509Certificate) keyStore.getCertificate(alias);
                    String sigalg = x509Certificate.getSigAlgName();
                    Signature signature = Signature.getInstance(sigalg);
                    signature.initVerify(publicKey);
                    signature.update(jsonText.getBytes(StandardCharsets.UTF_8));
                    boolean verify = signature.verify(jsonText.getBytes(StandardCharsets.UTF_8));
                    return verify;
                }

                // if (key instanceof PrivateKey) {
                //
                //     System.out.println("PrivateKey");
                //
                //     PrivateKey privateKey = (PrivateKey) key;
                //     X509Certificate x509Certificate = (X509Certificate) keyStore.getCertificate(alias);
                //     String sigalg = x509Certificate.getSigAlgName();
                //     Signature signature = Signature.getInstance(sigalg);
                //     signature.initSign(privateKey);
                //     signature.update(jsonText.getBytes(StandardCharsets.UTF_8));
                //     byte[] sign = signature.sign();
                // }
            }

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return false;
    }



    public static void main(String[] args) {

        String jsonText = "{\"code\":\"SUCCESS\",\"content\":{\"test0\":\"0\",\"test1\":\"1\",\"test2\":\"2\",\"test3\":\"3\",\"test4\":\"4\",\"test5\":\"5\",\"test6\":\"6\",\"test7\":\"7\",\"test8\":\"8\",\"test9\":\"9\"},\"info\":\"测试成功\"}";
        String passWord = "chench";

        // String prikPath = "C:\\Users\\chench\\Desktop\\Temp\\ca\\ca\\certs\\ca.p12";
        // String prikPath = "C:\\Users\\chench\\Desktop\\Temp\\ca\\ca\\certs\\client.p12";
        String prikPath = "C:\\Users\\chench\\Desktop\\Temp\\ca\\ca\\certs\\server.p12";

        String signData = KeyUtil.sign(prikPath, passWord, jsonText);
        System.out.println("sign ： " + signData);

        // String pubkPath = "C:\\Users\\chench\\Desktop\\Temp\\ca\\ca\\certs\\ca.cer";
        // String pubkPath = "C:\\Users\\chench\\Desktop\\Temp\\ca\\ca\\certs\\client.cer";
        String pubkPath = "C:\\Users\\chench\\Desktop\\Temp\\ca\\ca\\certs\\server.cer";

        boolean verifyFlag = KeyUtil.verify(pubkPath, signData, jsonText);
        System.out.println("verify ： " + verifyFlag);
    }

}
